#include <QtGui/QLineEdit>
#include <QtGui/QToolButton>
#include <QtGui/QPushButton>
#include <QtGui/QHBoxLayout>
#include <QtGui/QLabel>
#include <QtGui/QMenu>
#include <QtGui/QAction>
#include <QtCore/QSettings>
#include "Editor.h"
#include "Const.h"
#include "FindReplaceWidget.h"

FindReplaceWidget::FindReplaceWidget(QWidget *parent) : QWidget(parent) {
	currentEditor = 0;
	replaceCount = 0;
	findCount = 0;
	
	findLine = new QLineEdit;
	findLine->setForegroundRole(QPalette::Light);
	connect(findLine,SIGNAL(returnPressed()),this,SLOT(find()));
	connect(findLine,SIGNAL(textChanged(const QString&)),this,SLOT(findTextChanged(const QString&)));
	
	defaultPalette = findLine->palette();
	redPalette.setColor(QPalette::Base,QColor(255,110,110));
	greenPalette.setColor(QPalette::Base,QColor(110,255,110));
	
	replaceLabel = new QLabel("<b>" + tr("And replace on") + "</b>");

	messageLabel = new QLabel;
	messageLabel->hide();
	
	replaceLine = new QLineEdit;
	connect(replaceLine,SIGNAL(returnPressed()),this,SLOT(replace()));

	findButton = new QToolButton;
	findButton->setAutoRaise(true);
	findButton->setIcon(QIcon(":/icons/find_next.png"));
	findButton->setFocusPolicy(Qt::ClickFocus);
	findButton->setToolTip(tr("Find"));
	findButton->setShortcut(QKeySequence("F3"));
	connect(findButton,SIGNAL(clicked()),this,SLOT(find()));
	
	findPreviousButton = new QToolButton;
	findPreviousButton->setAutoRaise(true);
	findPreviousButton->setIcon(QIcon(":/icons/find_previous.png"));
	findPreviousButton->setFocusPolicy(Qt::ClickFocus);
	findPreviousButton->setToolTip(tr("Find previous entry"));
	findPreviousButton->setShortcut(QKeySequence("Shift+F3"));
	connect(findPreviousButton,SIGNAL(clicked()),this,SLOT(findPrevious()));
	
	replaceButton = new QToolButton;
	replaceButton->setAutoRaise(true);
	replaceButton->setIcon(QIcon(":/icons/find_and_replace.png"));
	replaceButton->setToolTip(tr("Replace"));;
	replaceButton->setFocusPolicy(Qt::ClickFocus);
	connect(replaceButton,SIGNAL(clicked()),this,SLOT(replace()));

	replaceAllButton = new QPushButton(tr("Replace all"));
	replaceAllButton->setFlat(true);
	replaceAllButton->hide();
	connect(replaceAllButton,SIGNAL(clicked()),this,SLOT(replaceAll()));
	
	cancelButton = new QToolButton;
	cancelButton->setAutoRaise(true);
	cancelButton->setIcon(QIcon(":/icons/close.png"));
	cancelButton->setShortcut(QKeySequence("Esc"));
	cancelButton->setToolTip(tr("Hide the panel"));
	connect(cancelButton,SIGNAL(clicked()),this,SLOT(hide()));
	
	optionsMenu = new QMenu(tr("Options"));

	matchCaseAction = new QAction(optionsMenu);
	matchCaseAction->setCheckable(true);
	matchCaseAction->setText(tr("Match case"));
	matchCaseAction->setShortcut(QKeySequence("Alt+2"));
	
	backwardAction = new QAction(optionsMenu);
	backwardAction->setCheckable(true);
	backwardAction->setText(tr("Backward"));
	backwardAction->setShortcut(QKeySequence("Alt+4"));
	
	regularExpAction = new QAction(optionsMenu);
	regularExpAction->setCheckable(true);
	regularExpAction->setText(tr("Regular expression"));
	regularExpAction->setShortcut(QKeySequence("Alt+5"));
	
	wholeWordAction = new QAction(optionsMenu);
	wholeWordAction->setCheckable(true);
	wholeWordAction->setText(tr("Search only whole words"));
	wholeWordAction->setShortcut(QKeySequence("Alt+3"));
	
	fromCursorAction = new QAction(optionsMenu);
	fromCursorAction->setCheckable(true);
	fromCursorAction->setText(tr("From cursor"));
	fromCursorAction->setShortcut(QKeySequence("Alt+1"));
	
	connect(fromCursorAction,SIGNAL(triggered()),this,SLOT(findSettingsChanged()));
	connect(wholeWordAction,SIGNAL(triggered()),this,SLOT(findSettingsChanged()));
	connect(regularExpAction,SIGNAL(triggered()),this,SLOT(findSettingsChanged()));
	connect(backwardAction,SIGNAL(triggered()),this,SLOT(findSettingsChanged()));
	connect(matchCaseAction,SIGNAL(triggered()),this,SLOT(findSettingsChanged()));
	
	optionsMenu->addAction(fromCursorAction);
	optionsMenu->addAction(matchCaseAction);
	optionsMenu->addAction(wholeWordAction);
	optionsMenu->addAction(backwardAction);
	optionsMenu->addAction(regularExpAction);
	
	optionsButton = new QToolButton;
	optionsButton->setIcon(QIcon(":/icons/settings.png"));
	optionsButton->setAutoRaise(true);
	optionsButton->setMenu(optionsMenu);
	optionsButton->setPopupMode(QToolButton::InstantPopup);
	optionsButton->setToolTip(tr("Settings"));
	
	QHBoxLayout *bottomLayout = new QHBoxLayout;
	bottomLayout->addWidget(optionsButton);
	bottomLayout->addWidget(new QLabel("<b>" + tr("Find") + "</b>"));
	bottomLayout->addWidget(findLine);
	bottomLayout->addWidget(findButton);
	bottomLayout->addWidget(findPreviousButton);
	bottomLayout->addWidget(replaceLabel);
	bottomLayout->addWidget(replaceLine);
	bottomLayout->addWidget(replaceButton);
	bottomLayout->addWidget(replaceAllButton);
	bottomLayout->addWidget(cancelButton);
	
	QVBoxLayout *mainLayout = new QVBoxLayout;
	mainLayout->addWidget(messageLabel);
	mainLayout->addLayout(bottomLayout);
	mainLayout->setContentsMargins(10,0,5,0);
	
	setLayout(mainLayout);
	loadSettings();
}

FindReplaceWidget::~FindReplaceWidget() {
	saveSettings();

	delete findLine;
	delete messageLabel;
	delete replaceLine;
	delete replaceLabel;
	delete findButton;
	delete findPreviousButton;
	delete replaceAllButton;
	delete replaceButton;
	delete cancelButton;
}

void FindReplaceWidget::find() {
	findCount++;
	
	if (findCount > 1) {
		currentEditor->findNextEntry();
		return;
	}
	
	replaceCount = 0;
	QString findText = findLine->text();
	findLine->setPalette(defaultPalette);
	
	if (currentEditor == 0) {
		hide();
		return;
	}
	if (findText.isEmpty()) {
		findLine->setFocus();
		return;
	}
	
	if (currentEditor->find(findText,regularExpAction->isChecked(),matchCaseAction->isChecked(),
			wholeWordAction->isChecked(),!backwardAction->isChecked(),fromCursorAction->isChecked()))
		findLine->setPalette(greenPalette);
	else
		findLine->setPalette(redPalette);
}

void FindReplaceWidget::findPrevious() {
	if (currentEditor)
		currentEditor->findPreviousEntry();
}

void FindReplaceWidget::replace() {
	QString findText = findLine->text();
	QString replaceText = replaceLine->text();
	
	if (currentEditor == 0) {
		hide();
		return;
	}
	if (findText.isEmpty()) {
		findLine->setFocus();
		return;
	}
	if (replaceText.isEmpty()) {
		replaceLine->setFocus();
		return;
	}
	replaceCount++;
	replaceAllButton->show();
	if (replaceCount <= 1)
		currentEditor->find(findText,regularExpAction->isChecked(),matchCaseAction->isChecked(),
			wholeWordAction->isChecked(),!backwardAction->isChecked(),fromCursorAction->isChecked());
	else {
		currentEditor->replace(replaceText);
		currentEditor->findNext();
	}
}

void FindReplaceWidget::replaceAll() {
	QString findText = findLine->text();
	QString replaceText = replaceLine->text();
	
	if (currentEditor == 0) {
		hide();
		return;
	}
	if (findText.isEmpty()) {
		findLine->setFocus();
		return;
	}
	if (replaceText.isEmpty()) {
		replaceLine->setFocus();
		return;
	}
	currentEditor->findAndReplaceAllEntries(findText,replaceText,regularExpAction->isChecked(),matchCaseAction->isChecked(),
			wholeWordAction->isChecked(),!backwardAction->isChecked(),fromCursorAction->isChecked());
}

void FindReplaceWidget::saveSettings() {
	QSettings settings(ORGANIZATION,PROGRAM_NAME);
	settings.setValue("FindReplaceWidget/MatchCase",matchCaseAction->isChecked());
	settings.setValue("FindReplaceWidget/BackWard",backwardAction->isChecked());
	settings.setValue("FindReplaceWidget/RegularExp",regularExpAction->isChecked());
	settings.setValue("FindReplaceWidget/WholeWord",wholeWordAction->isChecked());
	settings.setValue("FindReplaceWidget/FromCursor",fromCursorAction->isChecked());
}

void FindReplaceWidget::loadSettings() {
	QSettings settings(ORGANIZATION,PROGRAM_NAME);
	matchCaseAction->setChecked(settings.value("FindReplaceWidget/MatchCase",true).toBool());
	backwardAction->setChecked(settings.value("FindReplaceWidget/BackWard",false).toBool());
	regularExpAction->setChecked(settings.value("FindReplaceWidget/RegularExp",false).toBool());
	wholeWordAction->setChecked(settings.value("FindReplaceWidget/WholeWord",true).toBool());
	fromCursorAction->setChecked(settings.value("FindReplaceWidget/FromCursor",false).toBool());
}

void FindReplaceWidget::showEvent(QShowEvent *) {
	findLine->setFocus();
	replaceAllButton->hide();
	replaceCount = 0;
	findCount = 0;
}

void FindReplaceWidget::setCurrentEditor(Editor *editor) {
	currentEditor = editor;
	replaceCount = 0;
	findCount = 0;
}

void FindReplaceWidget::findTextChanged(const QString&) {
	replaceCount = 0;
	find();
	findCount = 0;
}

void FindReplaceWidget::findSettingsChanged() {
	findCount = 0;
	find();
	//currentEditor->changeFindSettings(regularExpAction->isChecked(),matchCaseAction->isChecked(),
//			wholeWordAction->isChecked(),!backwardAction->isChecked(),fromCursorAction->isChecked());
}
